package com.kate.mall.bff.wx.java8;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author 新梦想.陈超
 * @version 2021.2
 * @Description: {TODO}
 * @date 2023/3/13 下午4:24
 */

public class _03_Optional {
    public static void main(String[] args) {
        //TODO 1.ifPresent 如果 Optional 中有值，则对该值调用 consumer.accept，否则什么也不做。

        Optional<Employee> optionalEmployee = Optional.ofNullable(getEmpById(10));
        optionalEmployee.ifPresent(u-> System.out.println(u.getName()));

        //TODO 2. orElse 如果 Optional 中有值则将其返回，否则返回 orElse 方法传入的参数
        Employee employee = Optional.ofNullable(getEmpById(10)).orElse(new Employee("张三", 18, 3333));
        System.out.println(employee);

        //TODO 3.orElseGet 当 Optional 中有值的时候，返回值；当 Optional 中没有值的时候，返回从该 Supplier 获得的值。
        Employee employee1 = Optional.ofNullable(getEmpById(10)).orElseGet(() -> new Employee("张三", 18, 3333));
        System.out.println(employee1);

        //TODO 4.orElseThrow 方法当 Optional 中有值的时候，返回值；没有值的时候会抛出异常，抛出的异常由传入的 exceptionSupplier 提供。
        Employee employee2 = Optional.ofNullable(getEmpById(18)).orElseThrow(()->new RuntimeException("用户信息不存在"));
        System.out.println(employee2);

        /* spring mvc中统一异常处理 可以使用
        @RequestMapping("/{id}")
        public User getUser(@PathVariable Integer id) {
            Optional<User> user = userService.getUserById(id);
            return user.orElseThrow(() -> new EntityNotFoundException("id 为 " + id + " 的用户不存在"));
        }

        @ExceptionHandler(EntityNotFoundException.class)
        public ResponseEntity<String> handleException(EntityNotFoundException ex) {
            return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
        }
         */

        //TODO 5.map  如果当前 Optional 为 Optional.empty，则依旧返回 Optional.empty；
        // 否则返回一个新的 Optional，该 Optional 包含的是：函数 mapper 在以 value 作为输入时的输出值。
        Optional<String> optionalMap = Optional.ofNullable(getEmpById(18))
                .map(e -> e.getName())
                .map(name -> name.toLowerCase())
                .map(name -> name.replace('_', ' '));;
        System.out.println(optionalMap.orElse("未知"));

        //TODO 6.flatMap flatMap 要求参数中的函数 mapper 输出的就是 Optional。
        Optional<String> optionalFlatMap = Optional.ofNullable(getEmpById(18))
                .flatMap(e -> Optional.of(e.getName()))
                .flatMap(name -> Optional.of(name.toLowerCase(Locale.ROOT)));
        System.out.println(optionalFlatMap.orElse("未知"));


        //TODO 7.filter filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤，如果包含的值满足条件，那么还是返回这个 Optional；否则返回 Optional.empty。
        Optional<Employee> optionalFilter = Optional.ofNullable(getEmpById(18))
                .filter(e -> e.getAge() > 30);
        System.out.println(optionalFilter.orElse(new Employee("Unknow", 22, 99)));

        //TODO Java9-  or
    }



    static Employee getEmpById(int id){
        List<Employee> employees = Arrays.asList(
                new Employee("张三", 18, 3333),
                new Employee("李四", 38, 55555),
                new Employee("王五", 50, 6666.66),
                new Employee("赵六", 16, 77777.77),
                new Employee("田七", 8, 8888.88)
        );
        List<Employee> collect = employees.stream().filter(e -> e.getAge() == id).collect(Collectors.toList());
        return collect.size()>0?collect.get(0):null;
    }
}
